home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Scheme -*-
-
- #|
-
- Copyright (c) 1986-91 Massachusetts Institute of Technology
-
- This material was developed by the Scheme project at the Massachusetts
- Institute of Technology, Department of Electrical Engineering and
- Computer Science. Permission to copy this software, to redistribute
- it, and to use it for any purpose is granted, subject to the following
- restrictions and understandings.
-
- 1. Any copy made of this software must include this copyright notice
- in full.
-
- 2. Users of this software agree to make their best efforts (a) to
- return to the MIT Scheme project any improvements or extensions that
- they make, so that these may be included in future releases; and (b)
- to inform MIT of noteworthy uses of this software.
-
- 3. All materials developed as a consequence of the use of this
- software shall duly acknowledge such use, in accordance with the usual
- standards of acknowledging credit in academic research.
-
- 4. MIT has made no warrantee or representation that the operation of
- this software will be error-free, and MIT is under no obligation to
- provide any services, by way of maintenance, update, or otherwise.
-
- 5. In conjunction with products arising from the use of this material,
- there shall be no use of the name of the Massachusetts Institute of
- Technology nor of any adaptation thereof in any advertising,
- promotional, or sales literature without prior written consent from
- MIT in each case.
-
- |#
-
- ;;;; Box and pointer diagram printer in Scheme
- ;; Uses the Henderson-Escher picture language.
-
- (define (show sexp)
- (draw (->picture sexp)))
-
- (define (->picture sexp)
- (let ((the-pict (convert sexp)))
- (above (pad (result 1 1 down-arrow) 1 (width the-pict))
- (picture the-pict)
- (/ 1 (1+ (depth the-pict))))))
-
- ;; CONVERT returns a data structure (made by RESULT) which contains
- ;; the dimensions (depth and width) of the structure as a rectangle
- ;; in "box" units (a cons-cell takes 2 boxes, an atom only one).
-
- (define result list)
- (define depth car)
- (define width cadr)
- (define picture caddr)
-
- (define (convert sexp)
- (if (atom? sexp)
- (result 1 1 (atom-picture sexp))
- (convert-pair (car sexp) (cdr sexp))))
-
- (define (convert-pair the-car the-cdr)
- (cond ((and (null? the-car) (null? the-cdr))
- (result 1 2 both-nil-cell))
- ((null? the-car)
- (convert-null-car (convert the-cdr)))
- ((null? the-cdr)
- (convert-null-cdr (convert the-car)))
- ((and (atom? the-car) (atom? the-cdr))
- (convert-both-atoms (convert the-car)
- (convert the-cdr)))
- (else (convert-general (convert the-car)
- (convert the-cdr)))))
-
- (define (convert-general the-car the-cdr)
- (let ((total-depth (max (+ 2 (depth the-car)) (depth the-cdr)))
- (car-width (max 3 (1+ (width the-car)))))
- (let ((total-width (+ car-width (width the-cdr))))
- (result total-depth
- total-width
- (beside (above (standard-cell car-width)
- (pad the-car (- total-depth 2) car-width)
- (/ 2 total-depth))
- (pad the-cdr total-depth (width the-cdr))
- (/ car-width total-width))))))
-
- (define (convert-null-cdr the-car)
- (let ((the-width (max 2 (width the-car)))
- (the-depth (+ 2 (depth the-car))))
- (result the-depth
- the-width
- (above (nil-cdr-cell the-width)
- (pad the-car (depth the-car) the-width)
- (/ 2 the-depth)))))
-
- (define (convert-null-car the-cdr)
- (if (< (* (+ 2 (depth the-cdr) (1+ (width the-cdr))))
- (* (depth the-cdr) (+ 3 (width the-cdr))))
- (convert-cdr-below the-cdr)
- (convert-cdr-beside the-cdr)))
-
- (define (convert-cdr-below the-cdr)
- (let ((the-width (1+ (width the-cdr)))
- (the-depth (+ 2 (depth the-cdr))))
- (result the-depth
- the-width
- (above (nil-car-below-cell the-width)
- (beside empty (picture the-cdr) (/ 1 the-width))
- (/ 2 the-depth)))))
-
- (define (convert-cdr-beside the-cdr)
- (let ((the-width (+ 3 (width the-cdr)))
- (the-depth (depth the-cdr)))
- (result the-depth
- the-width
- (beside (nil-car-beside-cell the-depth)
- (picture the-cdr)
- (/ 3 the-width)))))
-
- (define (convert-both-atoms the-car the-cdr)
- (result 3
- 2
- (above both-atom-cell
- (beside (picture the-car)
- (picture the-cdr)
- .5)
- (/ 2 3))))
-
- (define (pad desc td tw)
- (define (do-one how pict target source)
- (if (= target source)
- pict
- (how pict empty (/ source target))))
- (do-one above
- (do-one beside (picture desc) tw (width desc))
- td
- (depth desc)))
-
- (define (standard-cell width)
- (beside left-standard
- (if (= width 3)
- right-standard
- (beside center-standard
- right-standard
- (/ (- width 3) (- width 2))))
- (/ 2 width)))
-
- (define (nil-cdr-cell width)
- (pad (result 2 2 standard-nil-cdr-cell) 2 width))
-
- (define (nil-car-below-cell width)
- (pad (result 2 2 standard-nil-car-below-cell) 2 width))
-
- (define (nil-car-beside-cell depth)
- (pad (result 1 3 standard-nil-car-beside-cell) depth 3))
-
- (define (atom-picture x)
- (atom-outline
- (cond ((null? x) slash)
- ((symbol? x)
- (text-picture (symbol->string x)))
- ((number? x)
- (text-picture (number->string x '(heur))))
- ((string? x)
- (text-picture
- (string-append double-quote-string
- (string-append x double-quote-string))))
- (else cross))))
-
- (define (atom-outline picture)
- (let ((kernel (together outline picture)))
- (lambda (rectangle)
- (kernel
- (make-rect (+vect (origin rectangle)
- (scale .05 (+vect (horiz rectangle)
- (vert rectangle))))
- (scale .9 (horiz rectangle))
- (scale .9 (vert rectangle)))))))
-
- ;;;; Primitive pictures
-
- ;; text-picture is in cscheme.scm or macscheme.scm, ...
-
- (define empty
- (make-picture '()))
- (define slash
- (Make-picture (list (make-segment (make-vect 0 0)
- (make-vect 1 1)))))
- (define outline
- (make-picture (list (make-segment (make-vect 0 0)
- (make-vect 0 1))
- (make-segment (make-vect 0 1)
- (make-vect 1 1))
- (make-segment (make-vect 1 1)
- (make-vect 1 0))
- (make-segment (make-vect 1 0)
- (make-vect 0 0)))))
- (define cross
- (make-picture (list (make-segment (make-vect 0 0)
- (make-vect 1 1))
- (make-segment (make-vect 0 1)
- (make-vect 1 0)))))
-
-
- (define down-bar
- (make-picture (list (make-segment (make-vect .5 .5)
- (make-vect .5 0)))))
-
- (define right-bar (rotate90 down-bar))
- (define up-bar (rotate90 right-bar))
- (define left-bar (rotate90 up-bar))
-
- (define down-arrow
- (make-picture (list (make-segment (make-vect .5 0)
- (make-vect .5 1))
- (make-segment (make-vect .3 .2)
- (make-vect .5 0))
- (make-segment (make-vect .7 .2)
- (make-vect .5 0)))))
- (define right-arrow (rotate90 down-arrow))
- (define up-arrow (rotate90 right-arrow))
- (define left-arrow (rotate90 up-arrow))
-
- (define arrow-down-cell
- (above (together outline down-bar)
- down-arrow
- .5))
-
- (define both-atom-cell
- (beside arrow-down-cell arrow-down-cell .5))
-
- (define left-standard
- (beside arrow-down-cell
- (above (together outline right-bar)
- empty
- .5)
- .5))
-
- (define right-standard
- (above right-arrow empty .5))
-
- (define center-standard
- (above (together left-bar right-bar)
- empty
- .5))
-
- (define nil-cell
- (together outline slash))
-
- (define both-nil-cell
- (beside nil-cell nil-cell .5))
-
- (define partial-nil-cell
- (above nil-cell empty .5))
-
- (define standard-nil-cdr-cell
- (beside arrow-down-cell partial-nil-cell .5))
-
- (define standard-nil-car-below-cell
- (beside partial-nil-cell arrow-down-cell .5))
-
- (define standard-nil-car-beside-cell
- (beside nil-cell
- (beside (together outline right-bar)
- right-arrow
- .5)
- (/ 1 3)))